package com.happok.onlineclass.usermanagement.authentication.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.happok.onlineclass.usermanagement.authentication.dao.RememberMeTokenDAO;
import com.happok.onlineclass.usermanagement.authentication.dataobject.RememberMeTokenDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.authentication.rememberme.PersistentRememberMeToken;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Optional;

@Service
public class RememberMeTokenService implements PersistentTokenRepository {

    @Autowired
    private RememberMeTokenDAO rememberMeTokenDao;

    @Override
    public void createNewToken(PersistentRememberMeToken token) {
        RememberMeTokenDO rememberMeTokenDO = new RememberMeTokenDO();
        rememberMeTokenDO.setSeries(token.getSeries());
        rememberMeTokenDO.setUsername(token.getUsername());
        rememberMeTokenDO.setLastUsed(token.getDate());
        rememberMeTokenDO.setToken(token.getTokenValue());
        rememberMeTokenDao.insert(rememberMeTokenDO);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateToken(String series, String tokenValue, Date lastUsed) {
        LambdaUpdateWrapper<RememberMeTokenDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(RememberMeTokenDO::getSeries, series);
        RememberMeTokenDO rememberMeTokenDO = new RememberMeTokenDO();
        rememberMeTokenDO.setToken(tokenValue);
        rememberMeTokenDO.setLastUsed(lastUsed);
        rememberMeTokenDao.update(rememberMeTokenDO, lambdaUpdateWrapper);
    }

    @Override
    public PersistentRememberMeToken getTokenForSeries(String seriesId) {
        LambdaQueryWrapper<RememberMeTokenDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RememberMeTokenDO::getSeries, seriesId);
        RememberMeTokenDO rememberMeToken = rememberMeTokenDao.selectOne(queryWrapper);
        return  Optional.ofNullable(rememberMeToken).map(a ->{
            return new PersistentRememberMeToken(a.getUsername(),a.getSeries(),a.getToken(),a.getLastUsed());
        }).orElse(null);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeUserTokens(String username) {
        LambdaQueryWrapper<RememberMeTokenDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RememberMeTokenDO::getUsername, username);
        rememberMeTokenDao.delete(queryWrapper);
    }
}